package com.irdstudio.efp.rule.service.impl;

import java.util.Collection;
import java.util.Map;
import java.util.Objects;

import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.ObjectFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.irdstudio.efp.rule.service.facade.DynamicExecuteDrools;
import com.irdstudio.efp.rule.service.util.DynamicExecuteDroolsFactory;
import com.irdstudio.efp.rule.service.vo.RuleEntity;

/**
 *
 * 动态drools执行
 *
 * @author Cytus_
 * @since 2018年6月2日 上午11:39:49
 * @version 1.0
 *
 */
@Service("dynamicExecuteDrools")
public class DynamicExecuteDroolsImpl implements DynamicExecuteDrools {

    private static Logger logger = LoggerFactory.getLogger(DynamicExecuteDroolsImpl.class);

    public boolean dynamicExecuteDrools(String ruleName, String droolsScript, Map<String, Object> params) throws Exception {

        logger.info("动态规则："+ ruleName +"开始执行......");
        DynamicExecuteDroolsFactory factory = DynamicExecuteDroolsFactory.getFactory();
        KieSession kieSession = null;
        boolean result = false;
        try {
            if (!factory.exist(ruleName)) {
                String wholeDroolsScript = droolsScriptDeal(ruleName, droolsScript);
                kieSession = factory.createKieSession(ruleName, wholeDroolsScript);
            } else {
                kieSession = factory.createKieSession(ruleName, null);
            }

            //RuleResultEntity executeResult = new RuleResultEntity();
            //kieSession.setGlobal("executeResult", executeResult);
            kieSession.insert(params);
            kieSession.fireAllRules();
            //final RuleResultEntity executeRlt = (RuleResultEntity) kieSession.getGlobal("executeResult");
            Collection<? extends Object> objects = kieSession.getObjects(new ObjectFilter() {

                @Override
                public boolean accept(Object object) {
                    return Objects.nonNull(object) && object instanceof RuleEntity;
                }
            });

            if (Objects.nonNull(objects) && !objects.isEmpty()) {
                result = true;
            }

            //handles.iterator().next().
            /*if (Objects.nonNull(executeRlt.getRules()) && !executeRlt.getRules().isEmpty()) {
                RuleEntity ruleEntity = executeRlt.getRules().parallelStream().filter(s -> ruleName.equals(s.getRuleId())).findFirst().orElse(null);
                if (Objects.nonNull(ruleEntity)) {
                    result = RuleEntity.PASS.equals(ruleEntity.getExecuteReslut());
                }
            }*/

            logger.info("动态规则："+ ruleName +"执行结果为:"+ result);;
        } catch (Exception e) {
            logger.error("动态规则："+ ruleName +"执行出现异常!", e);
            throw e;
        } finally {
            if (Objects.nonNull(kieSession)) {
                kieSession.dispose();
            }
        }


        return result;
    }

    @Override
    public void compileDynamicRule(String ruleName, String droolsScript) throws Exception {
        DynamicExecuteDroolsFactory factory = DynamicExecuteDroolsFactory.getFactory();
        String wholeDroolsScript = droolsScriptDeal(ruleName, droolsScript);
        if (!factory.exist(ruleName)) {
            factory.createKieSession(ruleName, wholeDroolsScript);
        }else  {
            factory.rebuildRule(ruleName, wholeDroolsScript);
        }
    }


    protected static String droolsScriptDeal(String ruleName, String droolsScript) {
        StringBuilder sb = new StringBuilder();

        sb.append("package rules.RULE").append(ruleName).append("\r\n");
        sb.append("\r\n");
        sb.append("import com.irdstudio.efp.rule.service.vo.*;").append("\r\n");
        sb.append("import java.util.*;").append("\r\n");
        sb.append("import java.math.BigDecimal;").append("\r\n");
        sb.append("\r\n");
        sb.append("dialect  \"mvel\"").append("\r\n");
        sb.append("\r\n");
        //sb.append("global RuleResultEntity executeResult;").append("\r\n");
        sb.append("\r\n");
        sb.append("rule '").append(ruleName).append("'").append("\r\n");
        sb.append("\t").append("lock-on-active true").append("\r\n");
        sb.append("\r\n");
        sb.append("\t").append("when").append("\r\n");
        //sb.append("\t\t").append("$r : ").append("RuleResultEntity();").append("\r\n");
        sb.append("\t\t").append(droolsScript).append("\r\n");
        sb.append("\t").append("then").append("\r\n");
        sb.append("\t\t").append("insert(new RuleEntity(RuleEntity.PASS, drools.getRule().getName()));").append("\r\n");
        //sb.append("\t\t").append("executeResult.addRuleResult(new RuleEntity(RuleEntity.PASS, drools.getRule().getName()));").append("\r\n");
        sb.append("end").append("\r\n");

        logger.info("最终生成的动态规则为:\r\n"+ sb.toString());

        return sb.toString();

    }


}
